package com.pic.mgt;

import java.util.HashMap;
import java.util.Map;

import com.pic.mgt.action.ScheduleAutoInspectMissUnitAction;
import com.pic.mgt.action.UnitMonitorControlAction;
import com.pic.mgt.cli.CommandLineArgParser;
import com.pic.mgt.config.ConfigurationException;
import com.pic.mgt.initials.InitialBeansExecuter;
import com.pic.mgt.initials.InitialOperationException;
import com.pic.mgt.scheduler.QuartzAutoJob;
import com.pic.mgt.scheduler.ScheduleAutoJobException;
import com.pic.mgt.scheduler.SchedulerException;
import com.pic.mgt.syushin.SyushinScheduler;
import com.pic.mgt.syushin.SyushinSchedulerImpl;
import com.pic.mgt.syushin.executer.bucket.SyushinBucketExecutionQuartzJobBean;

public class SyushinLauncher extends Launcher {
	private static SyushinLauncher syushinLauncher = null;
	
	private SyushinLauncher(CommandLineArgParser igalaxyCLI) throws SystemLaunchException {
		super(igalaxyCLI);
		
		// (1) 執行系統(集信)初始化動作
		try {
			InitialBeansExecuter syushinInitialBeansExecuter =
				applicationContext.getBean("syushinInitialBeansExecuter",
						InitialBeansExecuter.class);
			// throws InitialOperationException
			syushinInitialBeansExecuter.doInitialization();
		} catch (InitialOperationException e) {
			// 不用寫 log (已經寫)
			
			// 拋出給呼叫者
			throw new SystemLaunchException("System launch failed.", e);
		}
		
		/*
		 *  (2) 若參數列有帶 'start' 參數，則自動執行開始動作。
		 *  (此 start 的參數，表示開始 Unit 監控)
		 */
		if (igalaxyCLI.hasArg("start")) {
			startSyushinMonitor();
		}
		
		// (3) 若參數列有帶 'recover'，
		if (igalaxyCLI.hasArg("recover")) {
			doAutoMissUnitInspectionAndRecoveryWithSystemDelay();
		}
		
		// (4) 開始 Scheduler 排程
		try {
			SyushinScheduler syushinScheduler = super.applicationContext.getBean(
																	"syushinSchedulerImpl",
																	SyushinSchedulerImpl.class);
			syushinScheduler.startScheduler();
		} catch (SchedulerException e1) {
			e1.printStackTrace();
		}
		
		
		
		// 以下為 測試 Bucket  _-----------------------
		
		//addBucketSchedule("POA", "POA1");
		//addBucketSchedule("POB", "POB1");
		//addBucketSchedule("AC1", "AC11");
		//addBucketSchedule("AC2", "AC21");
		//addBucketSchedule("AC3", "AC31");
		//addBucketSchedule("MS1", "MS11");
		//addBucketSchedule("MS2", "MS21");
		//addBucketSchedule("MS3", "MS31");
		//addBucketSchedule("PS1", "PS11");
		//addBucketSchedule("PS2", "PS21");
		//addBucketSchedule("PS3", "PS31");
		//addBucketSchedule("ST1", "ST11");
		//addBucketSchedule("TRC", "TRC1");
		//addBucketSchedule("CLB", "CLB1");
		//addBucketSchedule("DLB", "DLB1");
		//addBucketSchedule("BTT", "BTT1");
		//addBucketSchedule("EDI", "EDI1");
		//addBucketSchedule("CMP", "CMP1");
		//addBucketSchedule("SAS", "SAS1");
		//addBucketSchedule("SAD", "SAD1");
		//addBucketSchedule("INI", "INI1");
		
		//removeBucketSchedule("POA", "POA1");
		//removeBucketSchedule("POB", "POB1");
		//removeBucketSchedule("AC1", "AC11");
		//removeBucketSchedule("AC2", "AC21");
		//removeBucketSchedule("AC3", "AC31");
		//removeBucketSchedule("MS1", "MS11");
		//removeBucketSchedule("MS2", "MS21");
		//removeBucketSchedule("MS3", "MS31");
		//removeBucketSchedule("PS1", "PS11");
		//removeBucketSchedule("PS2", "PS21");
		//removeBucketSchedule("PS3", "PS31");
		//removeBucketSchedule("ST1", "ST11");
		//removeBucketSchedule("TRC", "TRC1");
		//removeBucketSchedule("CLB", "CLB1");
		//removeBucketSchedule("DLB", "DLB1");
		//removeBucketSchedule("BTT", "BTT1");
		//removeBucketSchedule("EDI", "EDI1");
		//removeBucketSchedule("CMP", "CMP1");
		//removeBucketSchedule("SAS", "SAS1");
		//removeBucketSchedule("SAD", "SAD1");
		//removeBucketSchedule("INI", "INI1");
		
		/*SimpleSyushinBucketProcess simpleSyushinBucketProcess =
		super.applicationContext.getBean("simpleSyushinBucketProcess",
				SimpleSyushinBucketProcess.class);
		simpleSyushinBucketProcess.perform("POA");
		simpleSyushinBucketProcess.perform("POB");*/
		
		
		// --- 測試  Message Miss Inspection 功能
		/*RunTimeSystemUtils.threadSleep(3000);
		SyushinMissBusinessUnitInspectActionImpl syushinMissBusinessUnitInspectActionImpl = 
					super.applicationContext.getBean("syushinMissBusinessUnitInspectActionImpl", SyushinMissBusinessUnitInspectActionImpl.class);
		syushinMissBusinessUnitInspectActionImpl.inspectMissUnitAndRecover();*/
		
		
		// --- 測試 business resend 功能
		/*RunTimeSystemUtils.threadSleep(3000);
		SyushinBusinessResendActionImpl syushinBusinessResendActionImpl = super.applicationContext.getBean(
				"syushinBusinessResendActionImpl",
				SyushinBusinessResendActionImpl.class);
		syushinBusinessResendActionImpl.resendBusiness("0050050201_POSR_112512000001");*/
		
		// --- 測試 bucket resend 功能
		/*RunTimeSystemUtils.threadSleep(3000);
		SyushinBucketResendActionImpl syushinBucketResendActionImpl = super.applicationContext.getBean(
				"syushinBucketResendActionImpl",
				SyushinBucketResendActionImpl.class);
		syushinBucketResendActionImpl.resendBucket("AC1B_11050001");*/
		
		// --- 測試 recover 功能
		/*RunTimeSystemUtils.threadSleep(3000);
		SyushinBusinessRecoverActionImpl syushinBusinessRecoverActionImpl = super.applicationContext.getBean(
				"syushinBusinessRecoverActionImpl",
				SyushinBusinessRecoverActionImpl.class);
		syushinBusinessRecoverActionImpl.recoverBusiness("0050050201_POAB_112512000001");*/
		
		// --- 測試 message recover 功能
		/*RunTimeSystemUtils.threadSleep(3000);
		SyushinMessageRecoverActionImpl haishinMessageRecoverActionImpl =
			super.applicationContext.getBean("syushinMessageRecoverActionImpl",
					SyushinMessageRecoverActionImpl.class);
		haishinMessageRecoverActionImpl.recoverMessage("POAB_11150008");*/
	}
	
	private void addBucketSchedule(String businessName, String scheduleName) {
		QuartzAutoJob quartzAutoJob =   
			super.applicationContext.getBean("quartzAutoJob",
											 QuartzAutoJob.class);
		
		// 排程群組名稱 
		String scheduleGroupName = businessName + "_package";
		// Job Data
		Map<String,String> jobData = new HashMap<String,String>();
		jobData.put(SyushinScheduler.JOB_DATA_BUSINESS_NNAME_KEY, businessName);
		
		try {
			// throws ScheduleAutoJobException
			quartzAutoJob.scheduleCronJob("0 0/5 9-18 * * ?",
										  SyushinBucketExecutionQuartzJobBean.class,
										  jobData,
										  scheduleName,
										  scheduleGroupName,
										  null);
		} catch (ScheduleAutoJobException e) {
			e.printStackTrace();
		}
	}
	
	private void removeBucketSchedule(String businessName, String scheduleName) {
		QuartzAutoJob quartzAutoJob =   
			super.applicationContext.getBean("quartzAutoJob",
											 QuartzAutoJob.class);
		
		try {
			quartzAutoJob.removeScheduledJob(businessName + "_package", scheduleName);
		} catch (ScheduleAutoJobException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected String[] applicationContextResources() {
		 String[] serviceResources =
	 		{"application-context-syushin.xml",
			 "syushin-executer.xml",
			 "syushin-executer-cfmt.xml",
			 "syushin-executer-target.xml",
			 "syushin-resource.xml",
			 "syushin-parser.xml",
			 "syushin-dao.xml",
			 "syushin-action.xml",
			 "syushin-action-shell.xml",
			 "syushin-quartz.xml",
			 "syushin-console.xml",
			 "common-parser.xml",
			 "common-dao.xml",
			 "common-action.xml",
			 "common-action-shell.xml",
			 "common-console.xml",
			 "common-system.xml",
			 "common-config.xml",
	 		 "common-scheduler.xml"};
	 return serviceResources;
	}

	@Override
	protected void checkSpecificConfiguration() throws ConfigurationException {
		// TODO 檢查設定檔內容

	}
	
	/**
	 * 載入系統並回傳 SyushinLauncher。
	 * @return
	 * @throws SystemLaunchException 
	 */
	public synchronized static SyushinLauncher getSyushinLauncher(CommandLineArgParser igalaxyCLI)
										throws SystemLaunchException {
		if (syushinLauncher == null) {
			syushinLauncher = new SyushinLauncher(igalaxyCLI);
		}
		return syushinLauncher;
	}
	
	/**
	 * 開始配信作業,包含開始 (1)監控業務 (2)監控訊息
	 */
	private void startSyushinMonitor() {
		UnitMonitorControlAction unitMonitorControlAction = 
			super.applicationContext.getBean("unitMonitorControlActionImpl",
											 UnitMonitorControlAction.class);
		
		unitMonitorControlAction.startUnitMonitor();
	}
	
	/**
	 * 將 "自動檢測lose業務和訊息並自動做恢復" 的處理動作加入排程, delay 一段系統
	 * 時間(由系統自行判斷)後才開始做。
	 */
	private void doAutoMissUnitInspectionAndRecoveryWithSystemDelay() {
		ScheduleAutoInspectMissUnitAction scheduleAutoInspectMissUnitAction =
						super.applicationContext.getBean("scheduleAutoInspectMissUnitActionImpl",
														 ScheduleAutoInspectMissUnitAction.class);
		scheduleAutoInspectMissUnitAction.scheduleAutoInspectMissUnitAndRecover();
	}
}
